package com.ybb.vue.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ybb.vue.common.Result;
import com.ybb.vue.common.util.OperationRecordsUtils;
import com.ybb.vue.domain.dto.UpdateUserPasswordDto;
import com.ybb.vue.domain.dto.UserDto;
import com.ybb.vue.entity.SysMenu;
import com.ybb.vue.entity.SysRole;
import com.ybb.vue.entity.SysUser;
import com.ybb.vue.mapper.SysMenuMapper;
import com.ybb.vue.mapper.SysRoleMapper;
import com.ybb.vue.mapper.SysUserMapper;
import com.ybb.vue.service.SysUserService;
import com.ybb.vue.common.util.StringUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class SysUserServieceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Autowired
    private SysUserMapper mapper;

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private SysMenuMapper sysMenuMapper;
    
    @Override
    public Result saveUser(UserDto userDto) {
        // 判断是否已存在该用户
        SysUser sysUser = mapper.selectOne(new QueryWrapper<SysUser>().eq("username", userDto.getUsername()));
        if (sysUser != null) {
            return Result.error("-1","该用户已存在！");
        }
        SysUser userInsert = new SysUser();
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        BeanUtils.copyProperties(userDto,userInsert);
        // 默认密码123456
        userInsert.setPassword(bCryptPasswordEncoder.encode("123456"));
        // 默认头像
        userInsert.setAvatar("20220829171459.jpg");
        this.save(userInsert);

        // 操作记录
        String content = "操作了用户表，【新增】了一条记录，记录id为：" + userInsert.getId();
        OperationRecordsUtils.createOperationRecords(content);
        return Result.success();
    }

    @Override
    public SysUser getByUsername(String username) {
        SysUser result = mapper.selectOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername,username));
        return result;
    }

    @Override
    public String getUserAuthorityInfo(String userId) {
        //  格式ROLE_admin,ROLE_common,system:user:resetPwd,system:role:delete,system:user:list,system:menu:query,system:menu:list,system:menu:add,system:user:delete,system:role:list,system:role:menu,system:user:edit,system:user:query,system:role:edit,system:user:add,system:user:role,system:menu:delete,system:role:add,system:role:query,system:menu:edit
        StringBuffer authority = new StringBuffer();
        // 根据用户id获得所有角色信息
        List<SysRole> roleList = sysRoleMapper.selectList(new QueryWrapper<SysRole>().inSql("id", "select role_id from sys_user_role where user_id=" + userId));
        if (roleList.size() > 0) {
            String roleCodeStrs = roleList.stream().map(r -> "ROLE_" + r.getCode()).collect(Collectors.joining(","));
            authority.append(roleCodeStrs);
        }
        // 遍历所有角色，获取所有菜单权限，而且不重复
        Set<String> menuCodeSet = new HashSet<>();
        for (SysRole sysRole : roleList) {
            List<SysMenu> sysMenuList = sysMenuMapper.selectList(new QueryWrapper<SysMenu>().inSql("id", "select menu_id from sys_role_menu where role_id=" + sysRole.getId()));
            for (SysMenu sysMenu : sysMenuList) {
                String perms = sysMenu.getPerms();
                if (StringUtil.isNotEmpty(perms)) {
                    menuCodeSet.add(perms);
                }
            }
        }
        if (menuCodeSet.size() > 0) {
            authority.append(",");
            String menuCode = menuCodeSet.stream().collect(Collectors.joining(","));
            authority.append(menuCode);
        }
        return authority.toString();
    }

    @Override
    public Result<?> updatePassword(UpdateUserPasswordDto dto) {
        SysUser sysUser = mapper.selectOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getId, dto.getId()));
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        if (sysUser == null) {
            return Result.error("-1", "用户不存在，请重新登陆");
        }
        if (!bCryptPasswordEncoder.matches(dto.getOldPassword(),sysUser.getPassword())) {
            return Result.error("-1", "原密码错误，请重试");
        }
        // 修改密码
        String password = bCryptPasswordEncoder.encode(dto.getPassword());
        sysUser.setPassword(password);

        // 操作记录
        String content = "操作了用户表，【修改密码】，记录id为：" + dto.getId();
        OperationRecordsUtils.createOperationRecords(content);
        return Result.success(mapper.updateById(sysUser));
    }

}
